﻿using System;
using System.Web.Mvc;

namespace LAPI.Web.Controllers.Usuario
{
    /// <summary>
    /// Controlador para /Usuario/
    /// </summary>
    public class UsuarioController : BaseController
    {
        #region /Usuario/Login
        /// <summary>
        /// GET: /Usuario/Login
        /// </summary>
        /// <returns>View Login.cshtml</returns>
        [HttpGet]
        public ActionResult Login()
        {
            return View();
        }

        /// <summary>
        /// POST: /Usuario/Login
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public String Login(LAPI.Data.Model.Usuario model)
        {
            LAPI.Business.Acciones.ResultadoAccion resultado;

            //1. Validamos la autenticacion del usuario
            LAPI.Business.Acciones.AccAutenticarUsuario autenticar = new Business.Acciones.AccAutenticarUsuario();
            resultado = autenticar.AutenticarUsuario(model);

            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //no valida, informamos del error
                return resultado.ResultadoToJson();
            }

            //2. Todo ha ido bien, autenticamos, y redirigmos a la principal
            Session["datosSesion"] = new LAPI.Business.DatosSesion(model.User);            
            resultado = new Business.Acciones.ResultadoAccion();
            resultado.setResultado(Business.Acciones.TipoResultado.REDIRECCION);
            resultado.addMensaje(
                mensaje: Url.Action(actionName: "Home", controllerName: "Home"),
                tipoMensaje: Business.Acciones.TipoMensaje.REDIRECCION
            );

            return resultado.ResultadoToJson();
        }
        #endregion


        #region /Usuario/Registro
        /// <summary>
        /// GET: /Usuario/Registro
        /// </summary>
        /// <returns>View Registro.cshtml</returns>
        [HttpGet]
        public ActionResult Registro()
        {
            return View();
        }

        /// <summary>
        /// POST: /Usuario/Registro
        /// </summary>
        /// <param name="model"></param>
        /// <returns>JSon con el resultado de la operación</returns>
        [HttpPost]
        public String Registro(LAPI.Data.Model.Usuario model)
        {
            LAPI.Business.Acciones.ResultadoAccion resultado;

            //1. Validamos que podamos registrar el usuario
            LAPI.Business.Acciones.AccValidarDatosCrearUsuario validacion = new Business.Acciones.AccValidarDatosCrearUsuario();
            resultado = validacion.ValidarDatosCrearUsuario(datosUsuario: model);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //no valida, informamos del error
                return resultado.ResultadoToJson();
            }

            //2. Registramos el usuario
            LAPI.Business.Acciones.AccRegistrarUsuario registrar = new Business.Acciones.AccRegistrarUsuario();
            resultado = registrar.RegistrarUsuario(datosUsuario: model);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //no valida, informamos del error
                return resultado.ResultadoToJson();
            }

            //3. Todo ha ido bien, redirigimos a la vista de login
            resultado = new Business.Acciones.ResultadoAccion();
            resultado.setResultado(Business.Acciones.TipoResultado.REDIRECCION);
            resultado.addMensaje(
                mensaje: Url.Action(actionName: "Login", controllerName: "Usuario"),
                tipoMensaje: Business.Acciones.TipoMensaje.REDIRECCION
            );

            return resultado.ResultadoToJson();
        }
        #endregion


        #region /Usuario/RecordarPassword

        /// <summary>
        /// GET: /Usuario/RecordarPassword
        /// </summary>
        /// <returns>View RecordarPassword.cshtml</returns>
        [HttpGet]
        public ActionResult RecordarPassword()
        {
            return View();
        }


        /// <summary>
        /// POST: /Usuario/RecordarPassword
        /// </summary>
        /// <param name="model">Modelo con los datos del usuario</param>
        /// <returns>Json con el resultado de la operación</returns>
        [HttpPost]
        public String RecordarPassword(LAPI.Data.Model.Usuario model)
        {
            LAPI.Business.Acciones.ResultadoAccion resultado;

            //1. Recordamos la contraseña
            LAPI.Business.Acciones.AccRecordarPasswordUsuario recordar = new Business.Acciones.AccRecordarPasswordUsuario();
            resultado = recordar.RecordarPasswordUsuario(model);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //no valida, informamos del error
                return resultado.ResultadoToJson();
            }

            //2. Todo ha ido bien, redirigimos a la vista de login
            resultado = new Business.Acciones.ResultadoAccion();
            resultado.setResultado(Business.Acciones.TipoResultado.REDIRECCION);
            resultado.addMensaje(
                mensaje: Url.Action(actionName: "Login", controllerName: "Usuario"),
                tipoMensaje: Business.Acciones.TipoMensaje.REDIRECCION
            );

            return resultado.ResultadoToJson();
        }

        #endregion


        #region /Usuario/Logout

        /// <summary>
        /// POST: /Usuario/Logout
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public void Logout()
        {
            Session["datosSesion"] = null;
        }

        #endregion


        #region /Usuario/Perfil

        /// <summary>
        /// GET: /Usuario/Perfil
        /// </summary>
        /// <returns>View Perfil.cshtml</returns>
        [HttpGet]
        public ActionResult Perfil()
        {
            LAPI.Business.DatosSesion datosSesion = (LAPI.Business.DatosSesion)Session["datosSesion"];

            if (datosSesion.getModelUsuario() != null)
                return View(datosSesion.getModelUsuario());
            else
                return View(new LAPI.Data.Model.Usuario());
        }

        #endregion


        #region /Usuario/Modificar

        /// <summary>
        /// GET: /Usuario/Modificar
        /// </summary>
        /// <returns>View Modificar.cshtml</returns>
        [HttpGet]
        public ActionResult Modificar()
        {

            if (Session["datosSesion"] != null)
            {
                LAPI.Business.DatosSesion datosSesion = (LAPI.Business.DatosSesion)Session["datosSesion"];

                if (datosSesion.getModelUsuario() != null)
                    return View(datosSesion.getModelUsuario());
                else
                    return View(new LAPI.Data.Model.Usuario());
            }
            else
                return View(new LAPI.Data.Model.Usuario());
        }

        /// <summary>
        /// POST: /Usuario/Modificar
        /// </summary>
        /// <param name="model">Modelo con los datos del usuario</param>
        /// <returns>Json con el resultado de la operación</returns>
        [HttpPost]
        public String Modificar(LAPI.Data.Model.Usuario model)
        {
            LAPI.Business.Acciones.ResultadoAccion resultado;
            LAPI.Business.DatosSesion datosSesion = null;

            //0. Comprobamos que haya sesión
            if (Session["datosSesion"] != null)
            {
                datosSesion = (LAPI.Business.DatosSesion)Session["datosSesion"];

                // agregamos el idusuario al modelo, para ayudar en la validación
                model.IdUsuario = datosSesion.getModelUsuario().IdUsuario;
            }
            else
            {
                resultado = new Business.Acciones.ResultadoAccion();
                resultado.setResultado(resultado: Business.Acciones.TipoResultado.ERROR);
                resultado.addMensaje(mensaje: "Ha caducado la sesión del usuario", tipoMensaje: Business.Acciones.TipoMensaje.ERROR);
            }

            //1. Validamos que podamos realizar el cambio            
            LAPI.Business.Acciones.AccValidarDatosModificacionUsuario validacion = new Business.Acciones.AccValidarDatosModificacionUsuario();
            resultado = validacion.ValidarDatosModificacionUsuario(datosUsuario: model);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //no valida, informamos del error
                return resultado.ResultadoToJson();
            }

            //2. Modificamos los datos del usuario
            LAPI.Business.Acciones.AccModificarUsuario modificar = new Business.Acciones.AccModificarUsuario();
            resultado = modificar.ModificarUsuario(datosUsuario: model);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //no valida, informamos del error
                return resultado.ResultadoToJson();
            }

            //3. Refrescamos los datos de sesion
            datosSesion.updateUsuario(nuevosDatos: model);
            Session["datosSesion"] = datosSesion;

            //4. Todo ha ido bien, redirigimos a la vista de perfil
            resultado = new Business.Acciones.ResultadoAccion();
            resultado.setResultado(Business.Acciones.TipoResultado.REDIRECCION);
            resultado.addMensaje(
                mensaje: Url.Action(actionName: "Perfil", controllerName: "Usuario"),
                tipoMensaje: Business.Acciones.TipoMensaje.REDIRECCION
            );

            return resultado.ResultadoToJson();
        }

        #endregion


        #region /Usuario/CambiarPassword

        /// <summary>
        /// GET: /Usuario/CambiarPassword
        /// </summary>
        /// <returns>View CambiarPassword.cshtml</returns>
        [HttpGet]
        public ActionResult CambiarPassword()
        {
            LAPI.Business.DatosSesion datosSesion = (LAPI.Business.DatosSesion)Session["datosSesion"];

            if (datosSesion.getModelUsuario() != null)
                return View(datosSesion.getModelUsuario());
            else
                return View(new LAPI.Data.Model.Usuario());
        }

        /// <summary>
        /// POST: /Usuario/CambiarPassword
        /// </summary>
        /// <param name="model">Modelo con los datos del usuario</param>
        /// <returns>Json con el resultado de la operación</returns>
        [HttpPost]
        public String CambiarPassword(LAPI.Data.Model.Usuario model)
        {
            LAPI.Business.Acciones.ResultadoAccion resultado;
            LAPI.Business.DatosSesion datosSesion = null;

            //0. Comprobamos que haya sesión
            if (Session["datosSesion"] != null)
            {
                datosSesion = (LAPI.Business.DatosSesion)Session["datosSesion"];

                // agregamos el idusuario al modelo, para ayudar en la validación
                model.IdUsuario = datosSesion.getModelUsuario().IdUsuario;
            }
            else
            {
                resultado = new Business.Acciones.ResultadoAccion();
                resultado.setResultado(resultado: Business.Acciones.TipoResultado.ERROR);
                resultado.addMensaje(mensaje: "Ha caducado la sesión del usuario", tipoMensaje: Business.Acciones.TipoMensaje.ERROR);
            }

            //1. Validamos que podamos realizar el cambio            
            LAPI.Business.Acciones.AccValidarCambiarPassword validacion = new Business.Acciones.AccValidarCambiarPassword();
            resultado = validacion.ValidarCambiarPassword(datosUsuario: model);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //no valida, informamos del error
                return resultado.ResultadoToJson();
            }

            //2. Modificamos la contraseña del usuario
            LAPI.Business.Acciones.AccCambiarPasswordUsuario modificar = new Business.Acciones.AccCambiarPasswordUsuario();
            resultado = modificar.CambiarPasswordUsuario(datosUsuario: model);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //no valida, informamos del error
                return resultado.ResultadoToJson();
            }

            //3. Todo ha ido bien, redirigimos a la vista de perfil
            resultado = new Business.Acciones.ResultadoAccion();
            resultado.setResultado(Business.Acciones.TipoResultado.REDIRECCION);
            resultado.addMensaje(
                mensaje: Url.Action(actionName: "Perfil", controllerName: "Usuario"),
                tipoMensaje: Business.Acciones.TipoMensaje.REDIRECCION
            );

            return resultado.ResultadoToJson();
        }


        #endregion

        //############# ADMINISTRACION  #############

        #region /Usuario/Gestion
        /// <summary>
        /// GET: /Usuario/Gestion
        /// </summary>
        /// <returns>View Gestion.cshtml</returns>
        [HttpGet]
        public ActionResult Gestion()
        {
            ActionResult resultado = comprobarErrorPermisoAdminSistema();
            if (resultado == null)
            {
                LAPI.Business.Gestores.GestorUsuarios gestor = new Business.Gestores.GestorUsuarios();

                LAPI.Business.DatosSesion datosSesion = (LAPI.Business.DatosSesion)Session["datosSesion"];

                return View(gestor.ObtenerTodos(datosSesion: datosSesion));
            }

            return resultado;
        }
        #endregion

        #region /Usuario/Crear

        /// <summary>
        /// GET: /Usuario/Crear
        /// </summary>
        /// <returns>View Crear.cshtml</returns>
        [HttpGet]
        public ActionResult Crear()
        {
            ActionResult resultado = comprobarErrorPermisoAdminSistema();
            if (resultado == null)
            {
                return View();
            }

            return resultado;
        }

        /// <summary>
        /// POST: /Usuario/Crear
        /// </summary>
        /// <param name="model">modelo de Usuario</param>
        /// <returns>String con el resultado JSON de la operacion</returns>
        [HttpPost]
        public String Crear(LAPI.Data.Model.Usuario model)
        {
            LAPI.Business.Acciones.ResultadoAccion resultado = null;

            //0. Comprobamos que haya sesión
            resultado = comprobarPermisoAdminSistema();
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //informamos del error
                return resultado.ResultadoToJson();
            }

            //1. Validamos que podamos crear
            LAPI.Business.Acciones.AccValidarDatosCrearUsuario validacion = new Business.Acciones.AccValidarDatosCrearUsuario();
            resultado = validacion.ValidarDatosCrearUsuario(datosUsuario: model);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //informamos del error
                return resultado.ResultadoToJson();
            }

            //2. Creamos
            LAPI.Business.Acciones.AccRegistrarUsuario crear = new Business.Acciones.AccRegistrarUsuario();
            resultado = crear.RegistrarUsuario(datosUsuario: model);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //informamos del error
                return resultado.ResultadoToJson();
            }

            //3. Todo ha ido bien, redirigimos a la vista de gestion
            resultado = new Business.Acciones.ResultadoAccion();
            resultado.setResultado(Business.Acciones.TipoResultado.REDIRECCION);
            resultado.addMensaje(
                mensaje: Url.Action(actionName: "Gestion", controllerName: "Usuario"),
                tipoMensaje: Business.Acciones.TipoMensaje.REDIRECCION
            );

            return resultado.ResultadoToJson();
        }
        #endregion

        #region /Usuario/Editar

        /// <summary>
        /// GET: /Usuario/Editar
        /// </summary>
        /// <param name="id">Identificador único del usuario</param>
        /// <returns>View Editar.cshtml</returns>
        [HttpGet]
        public ActionResult Editar(Int32 id)
        {
            ActionResult resultado = comprobarErrorPermisoAdminSistema();
            if (resultado == null && id != 0)
            {
                LAPI.Business.Gestores.GestorUsuarios gestor = new Business.Gestores.GestorUsuarios();
                return View(gestor.ObtenerPorId(IdUsuario: id));
            }

            return resultado;
        }

        /// <summary>
        /// POST: /Usuario/Editar
        /// </summary>
        /// <param name="model">modelo de Usuario</param>
        /// <returns>String con el resultado JSON de la operacion</returns>
        [HttpPost]
        public String Editar(LAPI.Data.Model.Usuario model)
        {
            LAPI.Business.Acciones.ResultadoAccion resultado = null;

            //0. Comprobamos que haya sesión
            resultado = comprobarPermisoAdminSistema();
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //informamos del error
                return resultado.ResultadoToJson();
            }

            //1. Validamos que podamos realizar el cambio            
            LAPI.Business.Acciones.AccValidarDatosModificacionUsuario validacion = new Business.Acciones.AccValidarDatosModificacionUsuario();
            resultado = validacion.ValidarDatosModificacionUsuario(datosUsuario: model);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //informamos del error
                return resultado.ResultadoToJson();
            }

            //2. Modificamos los datos
            LAPI.Business.Acciones.AccModificarUsuario modificar = new Business.Acciones.AccModificarUsuario();
            resultado = modificar.ModificarUsuario(datosUsuario: model);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //informamos del error
                return resultado.ResultadoToJson();
            }

            //3. Todo ha ido bien, redirigimos a la vista de gestion
            resultado = new Business.Acciones.ResultadoAccion();
            resultado.setResultado(Business.Acciones.TipoResultado.REDIRECCION);
            resultado.addMensaje(
                mensaje: Url.Action(actionName: "Gestion", controllerName: "Usuario"),
                tipoMensaje: Business.Acciones.TipoMensaje.REDIRECCION
            );

            return resultado.ResultadoToJson();
        }
        #endregion

        #region /Usuario/Eliminar

        /// <summary>
        /// GET: /Usuario/Eliminar
        /// </summary>
        /// <param name="id">Identificador único del usuario</param>
        /// <returns>String con el resultado JSON</returns>
        [HttpGet]
        public String Eliminar(Int32 id)
        {
            LAPI.Business.Acciones.ResultadoAccion resultado = null;

            //0. Comprobamos que haya sesión
            resultado = comprobarPermisoAdminSistema();
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //informamos del error
                return resultado.ResultadoToJson();
            }

            //1. Eliminamos
            LAPI.Business.Acciones.AccEliminarUsuario eliminar = new LAPI.Business.Acciones.AccEliminarUsuario();
            LAPI.Data.Model.Usuario model = new LAPI.Data.Model.Usuario();
            model.IdUsuario = id;
            resultado = eliminar.EliminarUsuario(datosUsuario: model);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //informamos del error
                return resultado.ResultadoToJson();
            }

            return resultado.ResultadoToJson();
        }

        #endregion

        #region /Usuario/Activar y /Usuario/Desactivar

        /// <summary>
        /// GET: /Usuario/Activar
        /// </summary>
        /// <param name="id">Identificador único del usuario</param>
        /// <returns>String con el resultado JSON</returns>
        [HttpGet]
        public String Activar(Int32 id)
        {
            LAPI.Business.Acciones.ResultadoAccion resultado = null;

            //0. Comprobamos que haya sesión
            resultado = comprobarPermisoAdminSistema();
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //informamos del error
                return resultado.ResultadoToJson();
            }

            //1. Activamos
            LAPI.Business.Acciones.AccEstadoUsuario activar = new LAPI.Business.Acciones.AccEstadoUsuario();
            LAPI.Data.Model.Usuario model = new LAPI.Data.Model.Usuario();
            model.activo = true;
            model.IdUsuario = id;
            resultado = activar.ActivarUsuario(datosUsuario: model);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //informamos del error
                return resultado.ResultadoToJson();
            }

            return resultado.ResultadoToJson();
        }

        /// <summary>
        /// GET: /Usuario/Desactivar
        /// </summary>
        /// <param name="id">Identificador único del usuario</param>
        /// <returns>String con el resultado JSON</returns>
        [HttpGet]
        public String Desactivar(Int32 id)
        {
            LAPI.Business.Acciones.ResultadoAccion resultado = null;

            //0. Comprobamos que haya sesión
            resultado = comprobarPermisoAdminSistema();
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //informamos del error
                return resultado.ResultadoToJson();
            }

            //1. Activamos
            LAPI.Business.Acciones.AccEstadoUsuario desactivar = new LAPI.Business.Acciones.AccEstadoUsuario();
            LAPI.Data.Model.Usuario model = new LAPI.Data.Model.Usuario();
            model.activo = false;
            model.IdUsuario = id;
            resultado = desactivar.DesactivarUsuario(datosUsuario: model);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //informamos del error
                return resultado.ResultadoToJson();
            }

            return resultado.ResultadoToJson();
        }

        #endregion

        #region Filtros Búsqueda

        /// <summary>
        /// POST: /Usuario/Buscar
        /// </summary>
        /// <param name="idusuarioFilter">Filtro por identificador</param>
        /// <param name="nombreFilter">Filtro por nombre/apellido/apellido2</param>
        /// <param name="dniFilter">Filtro por dni</param>
        /// <param name="emailFilter">Filtro por email</param>
        /// <returns>_ListadoUsuario.cshtml</returns>
        [HttpPost]
        public ActionResult Buscar(String idusuarioFilter, String nombreFilter, String dniFilter, String emailFilter)
        {

            ActionResult resultado = comprobarErrorPermisoAdminSistema();
            if (resultado == null)
            {
                LAPI.Business.Gestores.GestorUsuarios gestor = new Business.Gestores.GestorUsuarios();

                //Creamos el filtro con los parametros posibles
                System.Collections.Hashtable filtro = new System.Collections.Hashtable();
                if (!String.IsNullOrEmpty(idusuarioFilter))
                    filtro.Add("idusuario", idusuarioFilter);
                if (!String.IsNullOrEmpty(nombreFilter))
                    filtro.Add("nombre", nombreFilter);
                if (!String.IsNullOrEmpty(dniFilter))
                    filtro.Add("dni", dniFilter);
                if (!String.IsNullOrEmpty(emailFilter))
                    filtro.Add("email", emailFilter);

                LAPI.Business.DatosSesion datosSesion = (LAPI.Business.DatosSesion)Session["datosSesion"];

                return PartialView("_ListadoUsuario", gestor.ObtenerBusqueda(filtroBusqueda: filtro, datosSesion: datosSesion));
            }

            return resultado;
        }

        #endregion
    }
}
